﻿using Csla;
using System;
using Csla.Serialization;
using BizControl.DalLinq;
using BizControl.Library.BusinessObjects.Models;
using BizControl.Resources;
using System.Linq;

namespace BizControl.Library.BusinessObjects.People
{
  [Serializable()]
  public class PersonModels : BusinessListBase<PersonModels, PersonModelBO>
  {
    #region  Business Methods

    private PersonBO _person;

    public PersonModelBO this[PersonModelBO personModelSearchFor]
    {
      get
      {
        foreach (PersonModelBO personModel in this)
        {
          if (personModel.Model.Id == personModelSearchFor.Model.Id)
          {
            return personModel;
          }
        }
        return null;
      }
    }

    public PersonModelBO AddModel(ModelBO model)
    {
      if (!(Contains(model.ModelId)))
      {
        PersonModelBO personModel = PersonModelBO.NewPersonModel(_person, model);
        this.Add(personModel);
        return personModel;
      }
      else
      {
        throw new InvalidOperationException(ExceptionsMessages.PersonAlreadyExistsInModel);
      }
    }

    public void Remove(Guid modelId)
    {
      foreach (PersonModelBO personModel in this)
      {
        if (personModel.Model.Id == modelId)
        {
          Remove(personModel);
          break;
        }
      }
    }

    public bool Contains(Guid modelId)
    {
      foreach (PersonModelBO personModel in this)
        if (personModel.Model.Id == modelId)
          return true;
      return false;
    }

    public bool ContainsDeleted(Guid modelId)
    {
      foreach (PersonModelBO personModel in DeletedList)
        if (personModel.Model.Id == modelId)
          return true;
      return false;
    }

    #endregion

    #region  Factory Methods

    internal static PersonModels NewPersonModels(PersonBO person)
    {
      return DataPortal.CreateChild<PersonModels>(person);
    }

    internal static PersonModels GetModelPeople(PersonModel[] data, PersonBO person)
    {
      return DataPortal.FetchChild<PersonModels>(data, person);
    }

    private PersonModels()
    { /* require use of factory methods */ }

    #endregion

    #region  Data Access

    private void Child_Create(PersonBO person)
    {
      if (person == null) throw new ArgumentNullException(ExceptionsMessages.PersonNullReference);
      _person = person;
      base.Child_Create();
    }

    private void Child_Fetch(PersonModel[] data, PersonBO person)
    {
      if (person == null) throw new ArgumentNullException(ExceptionsMessages.PersonNullReference);
      _person = person;
      if (data == null) return;
      this.RaiseListChangedEvents = false;
      foreach (var child in data)
        Add(PersonModelBO.GetPersonModel(child, person));
      this.RaiseListChangedEvents = true;
    }

    #endregion
  }
}
